package com.octopus.yangj.customized.controller;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.octopus.kernal.controller.AbstractCustomizedController;
import com.octopus.kernal.ui.builder.DetailTableBuilder;
import com.octopus.yangj.customized.service.LogService;
import com.octopus.yangj.generated.controller.EmployeeValidator;
import com.octopus.yangj.generated.controller.SearchEmployeeCommand;
import com.octopus.yangj.generated.model.EmployeeStruct;
import com.octopus.yangj.generated.service.EmployeeService;

@Controller
@RequestMapping("/user/x")
public class CustomizedEmployeeController extends AbstractCustomizedController<EmployeeStruct, SearchEmployeeCommand, Long>{
	
    @Autowired
    private EmployeeValidator userValidator;
    
    @Autowired
    private DetailTableBuilder<EmployeeStruct> detailTableBuilder;
	
    @Autowired
    protected EmployeeService userService;
    
    @Autowired
    private LogService logService;
    
    @RequestMapping(value = "/query.o", method = RequestMethod.GET)
    public String back(HttpServletRequest request){
   		return "redirect:/common/home.o";
    }
    
    @RequestMapping(value = "/profile.o", method = RequestMethod.GET)
    public String profileView(Model model, HttpServletRequest request,
        @ModelAttribute
        EmployeeStruct entity) {
    	if(!SecurityUtils.getSubject().isPermitted("profile:edit")){
    		return "redirect:/common/unauthorized.o";
    	}
        model.addAttribute("ACTION", "view");
        EmployeeStruct entity2 = userService.getEntity((Long) SecurityUtils.getSubject().getPrincipal());
        try {
            BeanUtils.copyProperty(entity, "attributeValues", entity2 .getAttributeValues());
        } catch (Exception _x) {
            _x.printStackTrace();
        }
        entity.setPassword("");
        String userDetailTable = detailTableBuilder.build(request, entity, userValidator.getMessageSource(), true, null, null);
        request.setAttribute("userDetailTable", userDetailTable);
        return "customized/user/profile";
    }
    
    @RequestMapping(value = "/profile_edit.o", method = RequestMethod.GET)
    public String profileEdit(Model model, HttpServletRequest request,
        @ModelAttribute
        EmployeeStruct entity, BindingResult errors) {
    	if(!SecurityUtils.getSubject().isPermitted("profile:edit")){
    		return "redirect:/common/unauthorized.o";
    	}
        model.addAttribute("ACTION", "edit");
        EmployeeStruct entity2 = userService.getEntity((Long) SecurityUtils.getSubject().getPrincipal());
        try {
            BeanUtils.copyProperty(entity, "attributeValues", entity2 .getAttributeValues());
        } catch (Exception _x) {
            _x.printStackTrace();
        }
        entity.setPassword("");
        List<String> readonly = new ArrayList<String>();
        readonly.add("roles");
        String userDetailTable = detailTableBuilder.build(request, entity, userValidator.getMessageSource(), false, readonly, null);
        String passwordNewHtml = "<input type=\"password\" id=\"password\" name=\"password\" value=\"\" >";
        String passwordOldHtml = "<input type=\"password\" id=\"password_old\" name=\"password_old\" value=\"\" >";
        String password = passwordOldHtml + "&nbsp;&nbsp;" + userValidator.getMessageSource().getMessage("label.user.field.password.old", new Object[] { }, LocaleContextHolder.getLocale()) + "<br>"
        					+ passwordNewHtml + "&nbsp;&nbsp;" + userValidator.getMessageSource().getMessage("label.user.field.password.new", new Object[] { }, LocaleContextHolder.getLocale());
        String userDetailTableNew = userDetailTable.replace(passwordNewHtml, password);
        request.setAttribute("userDetailTable", userDetailTableNew);
        return "customized/user/profile";
    }

    @RequestMapping(value = "/profile_edit.o", method = RequestMethod.POST)
    public String saveProfileEdit(Model model, HttpServletRequest request,
        @ModelAttribute
        EmployeeStruct entity, BindingResult errors) {
    	Long id = (Long) SecurityUtils.getSubject().getPrincipal();
    	if(!SecurityUtils.getSubject().isPermitted("profile:edit")){
    		return "redirect:/common/unauthorized.o";
    	}
    	String passwordOld = userService.getEntity(id).getPassword();
    	String passwordOldInput = request.getParameter("password_old");
    	if( StringUtils.hasText(passwordOldInput) ) {
    		passwordOldInput = new Sha256Hash(passwordOldInput).toHex();
	    	if(!passwordOld.equals(passwordOldInput)){
	    		errors.rejectValue("password", "error.user.field.password.old.wrong", new Object[] {}, "Old password inputed is invalidate!");
	    		return profileEdit(model, request, entity, errors);
	    	}
    	}
        if( StringUtils.hasText(entity.getPassword()) ) {
        	entity.setPassword( new Sha256Hash(entity.getPassword()).toHex());
        }else{
        	entity.setPassword(passwordOld);
        }
        entity.setId(id);
        entity.setName(entity.getUsername());
        EmployeeStruct entity2 = userService.getEntity(id);
        entity.setRoles(entity2.getRoles());
        userValidator.validate(entity, errors);
        if (errors.hasErrors()) {
            return profileEdit(model, request, entity, errors);
        }
        try {
            userService.updateEntity(entity);
            logService.log("user", "edit", entity.getName());
        } catch (UncategorizedSQLException _x) {
            _x.printStackTrace();
            errors.rejectValue("id", "error.common.model.exist", "The entity has already existed.");
            return profileEdit(model, request, entity, errors);
        }
        errors.rejectValue("username", "label.common.save.successfully", new Object[] {}, "Save Successfully!");
        return profileView(model, request, entity);
    }
    
    @Override
	public String create(Model model, HttpServletRequest request, EmployeeStruct entity) {
		entity.setPassword("");
		return null;
	}
	
	@Override
	public String saveCreate(Model model, HttpServletRequest request, EmployeeStruct entity,
			BindingResult errors) {
		entity.setPassword(new Sha256Hash(entity.getPassword()).toHex());
		entity.setName(entity.getUsername());
		return null;
	}

	@Override
	public String edit(Model model, HttpServletRequest request, Long id, EmployeeStruct entity) {
		entity.setPassword("");
		return null;
	}

	@Override
	public String saveEdit(Model model, HttpServletRequest request, Long id, EmployeeStruct entity,
			BindingResult errors) {
		entity.setName(entity.getUsername());
        if( StringUtils.hasText(entity.getPassword()) ) {
        	entity.setPassword( new Sha256Hash(entity.getPassword()).toHex());
        }else{
        	entity.setPassword(userService.getEntity(id).getPassword());
        }
		return null;
	}
	
	@Override
	public String view(Model model, HttpServletRequest request, Long id, EmployeeStruct entity) {
		entity.setPassword("");
		return null;
	}

	@Override
	public String delete(Model model, HttpServletRequest request, Long id) {
		Assert.isTrue( id != 1, "Cannot delete admin user" );
		return null;
	}

}
